package com.modeler.single_flowable_modeler.controller;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.editor.language.json.converter.BpmnJsonConverter;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.repository.Deployment;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.ui.common.model.RemoteUser;
import org.flowable.ui.common.model.UserRepresentation;
import org.flowable.ui.common.security.SecurityUtils;
import org.flowable.ui.modeler.domain.Model;
import org.flowable.ui.modeler.serviceapi.ModelService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.util.List;

@RestController
@RequestMapping("/aapp")
public class AccountController {
    // 主要是这个springbean
    //        需要flowable-spring-boot-starter自动注入
    //     or flowable-engine和flowable-spring一起手动注入
    @Autowired
    private RepositoryService repositoryService;
    // 这个springbean是flowable-ui-modeler-rest中的flowable-ui-modeler-logic的自带的
    @Autowired
    private ModelService modelService;

    /**
     * 部署流程
     */
    @GetMapping("/deploy")
    public String deploy(String modelId) {
        // 通过act_de_model中存放的Modeler内容来部署
        Model modelData = modelService.getModel(modelId);
        ObjectNode modelNode = null;
        try {
            // 获取模型数据
            byte[] bytes = modelService.getBpmnXML(modelData);
            if (null == bytes) {
                System.out.println("模型数据为空，请先设计流程并成功保存，再进行发布。");
                return "模型数据为空，请先设计流程并成功保存，再进行发布。";
            }
            // 校验流程图是否标准
            modelNode = (ObjectNode) new ObjectMapper().readTree(modelData.getModelEditorJson());
            BpmnModel model = new BpmnJsonConverter().convertToBpmnModel(modelNode);
            if (model.getProcesses().size() == 0) {
                System.out.println("数据模型不符要求，请至少设计一条主线流程。");
                return "数据模型不符要求，请至少设计一条主线流程。";
            }
            // 流程文件名称
            String processName = modelData.getName() + ".bpmn20.xml";
            // 部署流程
            Deployment deploy = repositoryService
                    .createDeployment()
                    .name(modelData.getName())
                    .addBytes(processName, bytes)
                    .deploy();
            List<ProcessDefinition> list = repositoryService.createProcessDefinitionQuery().deploymentId(deploy.getId()).list();
            // 设置流程分类
            String processDefinitionId = "";
            for (ProcessDefinition processDefinition : list) {
                System.out.println("部署成功,流程ID:"+processDefinition.getId());
                processDefinitionId = processDefinition.getId();
            }
            return "部署成功,流程ID:"+processDefinitionId;
        } catch (IOException e) {
            e.printStackTrace();
            return e.getMessage();
        }
    }

    /**
     * 模拟用户返回
     * @return
     */
    @GetMapping(value = "/rest/account", produces = "application/json")
    public UserRepresentation getAccount() {
        // 这个user类是flowable中的
        org.flowable.idm.api.User user = new RemoteUser();
        user.setId("admin");
        // 这个是后台认证需要放入的
        SecurityUtils.assumeUser(user);
        // 这个是返回给前端用的
        UserRepresentation userRepresentation = new UserRepresentation();
        userRepresentation.setId("admin");
        return userRepresentation;
    }
}
